#ifndef _ESTANDARDTREE_H_
#define _ESTANDARDTREE_H_

#include <buola/widgets/ctreebox.h>
#include <buola/gui/cpropertyfield.h>

namespace buola { namespace gui {

template<typename tType> class EStandardTree : public CTreeBox
{
public:
    EStandardTree()
    {
        mNumNodes=0;
        mMainItem=nullptr;
        AddField(new CPropertyField(L"pointer",L"Item pointer",
                                L"Item pointer"),ID_FIELD_POINTER);
        FillTree();
    }

    ~EStandardTree()
    {
    }

    tType* GetItem(SNode *pNode)
    {
        return (tType*)pNode->Value(ID_FIELD_POINTER).Get<void*>();
    }

    SNode *GetNodeFromItem(tType *pItem,SNode *pFrom=nullptr)
    {
        if(!pFrom)
        {
            for(int i=0;i<GetNodeCount();i++)
            {
                SNode *lReturn=GetNodeFromItem(pItem,mTBN[i]);
                if(lReturn) return lReturn;             
            }
            return nullptr;
        }
        else
        {
            if(((tType*)pFrom->Value(ID_FIELD_POINTER).Get<void*>())==pItem)
                return pFrom;

            for(int i=0;i<pFrom->mChildren.size();i++)
            {
                SNode *lReturn=GetNodeFromItem(pItem,pFrom->mChildren[i]);
                if(lReturn) return lReturn;             
            }
            return nullptr;
        }
    }

    void SelectItem(tType *pItem)
    {
        SelectNode(GetNodeFromItem(pItem));
    }

    void CreateAndSet(CWindow *pParent,const CPoint_d &pPos,
                    const CSize_d &pSize,tType *pMainItem)
    {
        mMainItem=pMainItem;
        Create(pParent,pPos,pSize);
    }

    void CreateAndSet(CWindow *pParent,tType *pMainItem)
    {
        mMainItem=pMainItem;
        Create(pParent);
    }

    void SetMainItem(tType *pMainItem)
    {
        mMainItem=pMainItem;
        
        FillTree();
    }

protected:
    void AddItem(SNode *pUnder,tType *pItem,bool pMakeSub)
    {
        int lCount=pItem->GetChildrenCount();
    
        for(int i=0,r=0;i<lCount;i++,r++)
        {
            tType *lItem=pItem->GetChild(i);

            SNode *lNode=AddNode(pUnder,lItem->GetTitle(),
                                      lItem->GetIcon());

            lNode->Value(ID_FIELD_POINTER).Set<void*>(lItem);

            if(pMakeSub)
            {
                AddItem(lNode,lItem,false);
            }   

            if(r>100)
            {
                r=0;
                Update();
            }
        }
    }

    void FillTree()
    {
        RemoveAllNodes();
        
        if(!mMainItem) return;

        SNode *lNode=AddNode(nullptr,mMainItem->GetTitle(),
                        mMainItem->GetIcon());

        lNode->Value(ID_FIELD_POINTER).Set<void*>(mMainItem);

        AddItem(lNode,mMainItem,false);

        Refresh();
    //  Sort(CListBox::SItem::SortAscending);
    }

public:
    void OnTreeChanged()
    {
    }

    void OnFillMenu(PMenu,bool)
    {
    }

    void OnNodeExpandedFirstTime(SNode *pNode)
    {
        for(int i=0;i<pNode->mChildren.size();i++)
        {
            SNode *lNode=pNode->mChildren[i];

            tType *lItem=(tType*)lNode->Value(ID_FIELD_POINTER).Get<void*>();
        
            AddItem(lNode,lItem,false);
        }
    }

////////////////// Data
protected:
    tType *mMainItem;
    int mNumNodes;
};

/*namespace gui*/ } /*namespace buola*/ }

#endif
